//
//  ZTRouteStack.m
//  ZTRouter
//
//  Created by 黄露 on 2019/5/30.
//  Copyright © 2019 huanglu. All rights reserved.
//

#import "ZTRouteStack.h"
#import "UIViewController+ZTRouter.h"

@interface ZTRouteStack ()

@property (nonatomic , strong) NSMutableArray *routeStacks;

@end

static ZTRouteStack *stack;

@implementation ZTRouteStack

- (instancetype) init {
    if (self = [super init]) {
        self.routeStacks = [NSMutableArray array];
    }
    return self;
}

+ (instancetype) shared {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (!stack) {
            stack = [[ZTRouteStack alloc] init];
        }
    });
    return stack;
}

- (void) push:(ZTRouterObject *)route {
    [self.routeStacks addObject:route];
}

- (UIViewController *) popForParam:(id)param {
    ZTRouteStackObject *last = [self.routeStacks lastObject];
    [self.routeStacks removeLastObject];
    if (last.vc.route.callback) {
        last.vc.route.callback(param);
    }
    return last.vc;
}

- (void) replaceAndPush:(ZTRouteStackObject *)route {
    [self popForParam:nil];
    [self push:route];
}

- (UIViewController *) popToName:(NSString *)name param:(nullable id)param {
    ZTRouteStackObject *stack = [self popVCToName:name];
    if (stack) {
        NSInteger index = [self.routeStacks indexOfObject:stack];
        [self.routeStacks removeObjectAtIndex:index];
    }
    UIViewController *vc = stack.vc;
    if (stack.vc.route.callback) {
        stack.vc.route.callback(param);
    }
    return vc;
}

- (UIViewController *) popToPath:(NSString *)path param:(nullable id)param {
    ZTRouteStackObject *stack = [self popVCToPath:path];
    if (stack) {
        NSInteger index = [self.routeStacks indexOfObject:stack];
        [self.routeStacks removeObjectAtIndex:index];
    }
    UIViewController *vc = stack.vc;
    if (stack.vc.route.callback) {
        stack.vc.route.callback(param);
    }
    return vc;
}

// 根据name获取
- (ZTRouteStackObject *) stackForName:(NSString *)name {
    __block ZTRouteStackObject *stack = nil;
    [self.routeStacks enumerateObjectsUsingBlock:^(ZTRouteStackObject *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([obj.vc.route.name isEqualToString:name]) {
            stack = obj;
            *stop = true;
        }
    }];
    return stack;
}

// 根据path获取
- (ZTRouteStackObject *) stackForPath:(NSString *)path {
    __block ZTRouteStackObject *stack = nil;
    [self.routeStacks enumerateObjectsUsingBlock:^(ZTRouteStackObject *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([obj.vc.route.path isEqualToString:path]) {
            stack = obj;
            *stop = true;
        }
    }];
    return stack;
}

// 在pop时，需要将栈中的 目标 之上的数据出栈
- (ZTRouteStackObject *) popVCToName:(NSString *)name {
    NSEnumerator *rator = [self.routeStacks reverseObjectEnumerator];
    ZTRouteStackObject *object = nil;
    while (object = [rator nextObject]) {
        if ([object.vc.route.name isEqualToString:name]) {
            return object;
        }
    }
    return nil;
}

- (ZTRouteStackObject *) popVCToPath:(NSString *)path {
    NSEnumerator *rator = [self.routeStacks reverseObjectEnumerator];
    ZTRouteStackObject *object = nil;
    while (object = [rator nextObject]) {
        if ([object.vc.route.path isEqualToString:path]) {
            return object;
        }
    }
    return nil;
}

- (UIViewController *) topStack {
    ZTRouteStackObject *stack = [self.routeStacks lastObject];
    return stack.vc;
}

- (UIViewController *) popToRootForParam:(id)param {
    ZTRouteStackObject *stack = [self.routeStacks firstObject];
    [self.routeStacks removeAllObjects];
    [self.routeStacks addObject:stack];
    if (stack.vc.route.callback) {
        stack.vc.route.callback(param);
    }
    [self push:stack];
    return stack.vc;
}

@end

@implementation ZTRouteStackObject

@end
